package com.yin.waimai.config;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * RabbitMQ配置类
 * 配置队列、交换机、绑定关系和消息转换器
 */
@Configuration
@EnableRabbit
public class RabbitMQConfig {

    // 队列名称常量
    public static final String NOTIFICATION_QUEUE = "notification.queue";
    public static final String ORDER_STATUS_QUEUE = "order.status.queue";
    public static final String DELIVERY_LOCATION_QUEUE = "delivery.location.queue";
    
    // 交换机名称常量
    public static final String NOTIFICATION_EXCHANGE = "notification.exchange";
    public static final String ORDER_EXCHANGE = "order.exchange";
    public static final String DELIVERY_EXCHANGE = "delivery.exchange";
    
    // 路由键常量
    public static final String NOTIFICATION_ROUTING_KEY = "notification.email";
    public static final String ORDER_STATUS_ROUTING_KEY = "order.status.update";
    public static final String DELIVERY_LOCATION_ROUTING_KEY = "delivery.location.update";

    /**
     * 创建通知队列
     * @return Queue 通知队列
     */
    @Bean
    public Queue notificationQueue() {
        return QueueBuilder.durable(NOTIFICATION_QUEUE).build();
    }

    /**
     * 创建订单状态队列
     * @return Queue 订单状态队列
     */
    @Bean
    public Queue orderStatusQueue() {
        return QueueBuilder.durable(ORDER_STATUS_QUEUE).build();
    }

    /**
     * 创建配送位置队列
     * @return Queue 配送位置队列
     */
    @Bean
    public Queue deliveryLocationQueue() {
        return QueueBuilder.durable(DELIVERY_LOCATION_QUEUE).build();
    }

    /**
     * 创建通知交换机
     * @return TopicExchange 通知交换机
     */
    @Bean
    public TopicExchange notificationExchange() {
        return new TopicExchange(NOTIFICATION_EXCHANGE);
    }

    /**
     * 创建订单交换机
     * @return TopicExchange 订单交换机
     */
    @Bean
    public TopicExchange orderExchange() {
        return new TopicExchange(ORDER_EXCHANGE);
    }

    /**
     * 创建配送交换机
     * @return TopicExchange 配送交换机
     */
    @Bean
    public TopicExchange deliveryExchange() {
        return new TopicExchange(DELIVERY_EXCHANGE);
    }

    /**
     * 绑定通知队列到通知交换机
     * @return Binding 绑定关系
     */
    @Bean
    public Binding notificationBinding() {
        return BindingBuilder
                .bind(notificationQueue())
                .to(notificationExchange())
                .with(NOTIFICATION_ROUTING_KEY);
    }

    /**
     * 绑定订单状态队列到订单交换机
     * @return Binding 绑定关系
     */
    @Bean
    public Binding orderStatusBinding() {
        return BindingBuilder
                .bind(orderStatusQueue())
                .to(orderExchange())
                .with(ORDER_STATUS_ROUTING_KEY);
    }

    /**
     * 绑定配送位置队列到配送交换机
     * @return Binding 绑定关系
     */
    @Bean
    public Binding deliveryLocationBinding() {
        return BindingBuilder
                .bind(deliveryLocationQueue())
                .to(deliveryExchange())
                .with(DELIVERY_LOCATION_ROUTING_KEY);
    }

    /**
     * 配置RabbitTemplate，使用JSON消息转换器
     * @param connectionFactory 连接工厂
     * @return RabbitTemplate 配置好的RabbitTemplate
     */
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate template = new RabbitTemplate(connectionFactory);
        template.setMessageConverter(new Jackson2JsonMessageConverter());
        return template;
    }

    /**
     * 配置监听器容器工厂，使用JSON消息转换器
     * @param connectionFactory 连接工厂
     * @return SimpleRabbitListenerContainerFactory 配置好的监听器容器工厂
     */
    @Bean
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setMessageConverter(new Jackson2JsonMessageConverter());
        return factory;
    }
}